// ignore_for_file: use_build_context_synchronously

import 'dart:async';
import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:geomancy/models/common_model.dart';
import 'package:geomancy/providers/user_provider.dart';
import 'package:geomancy/tools/auth_login.dart';
import 'package:geomancy/tools/config.dart';
import 'package:geomancy/tools/localstorage.dart';
import 'package:provider/provider.dart';

// ignore: constant_identifier_names
enum Method { GET, POST, DELETE, PUT, PATCH, HEAD }
//使用：MethodValues[Method.POST]
const methodValues = {
  Method.GET: "get",
  Method.POST: "post",
  Method.DELETE: "delete",
  Method.PUT: "put",
  Method.PATCH: "patch",
  Method.HEAD: "head",
};

BaseOptions options = BaseOptions(
  //阿里云生产环境
  baseUrl: LocalConfig.appServerAddress,
  connectTimeout: const Duration(seconds: 30),
  receiveTimeout: const Duration(seconds: 30),
  contentType: Headers.jsonContentType,
  responseType: ResponseType.plain,
);

class Fetch {
  static final Dio _dio = Dio(options);

  static Future<Response> request(
    Method method,
    String path,
    {
      dynamic params,
      required BuildContext context,
      String? baseUrl,
      dynamic headerOption
    }
  ) async {
    print('path==$path');
    print('params==$params');
    final token = context.read<UserProvider>().getToken;
    print('token==$token');
    _dio.options.headers = {
      'token': token
    };
    if (baseUrl != null && baseUrl != '') {
      _dio.options.baseUrl = baseUrl;
    } else {
      _dio.options.baseUrl = LocalConfig.appServerAddress;
    }
    if (headerOption != null) {
      _dio.options.headers = headerOption;
    }
    try {
      dynamic data;
      dynamic queryParameters;
      if (method == Method.GET) {
        queryParameters = params;
      }
      if (method == Method.POST) {
        data = params;
      }
      Response response = await _dio.request(path,
        data: data,
        queryParameters: queryParameters,
        options: Options(method: methodValues[method])
      );
      ///有baseurl就说明是第三方url。格式可能不一样
      if (baseUrl != null) {
        return response;
      }
      final CommonModel res = CommonModel.fromJson(json.decode(response.toString()));
      final httpStatus = res.code;
      switch (httpStatus) {
        case 401:
          //token过期，需要跳转登录界面。
          context.read<UserProvider>().clearStore();
          final pref = await LocalStorage.getInstance();
          pref.clear();
          AliAuthLoginTools.login(context);
          break;
        default:
          break;
      }
      return response;
    } on DioException catch (e) {
      if (e.type == DioExceptionType.connectionTimeout || e.type == DioExceptionType.receiveTimeout || e.type == DioExceptionType.sendTimeout) {
        Timer(const Duration(seconds: 1), () {
          EasyLoading.dismiss();
          EasyLoading.showToast('网络请求超时');
        });
        rethrow;
      }
      final CommonModel res = CommonModel.fromJson(json.decode(e.response.toString()));
      final httpStatus = res.code;
      switch (httpStatus) {
        case 202:
          //数据重复，返回前端做业务处理。
          return e.response!;
        case 401:
          //token过期，需要跳转登录界面。
          AliAuthLoginTools.login(context);
          break;
        case 403:
          //未注册，返回response做业务处理。
          return e.response!;
        case 404:
          return e.response!;
        default:
          Timer(const Duration(seconds: 1), () {
            EasyLoading.dismiss();
            EasyLoading.showToast(res.message);
          });
          break;
      }
      rethrow;
    }
  }
}